home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / kcl / akcl / kcl.lha / c / num_arith.c < prev    next >
C/C++ Source or Header  |  1987-06-04  |  29KB  |  1,516 lines

  1. /*
  2. (c) Copyright Taiichi Yuasa and Masami Hagiya, 1984.  All rights reserved.
  3. Copying of this file is authorized to users who have executed the true and
  4. proper "License Agreement for Kyoto Common LISP" with SIGLISP.
  5. */
  6.  
  7. /*
  8.     Arithmetic operations
  9. */
  10. #include "include.h"
  11. #include "num_include.h"
  12.  
  13. object
  14. bignum2(most, least)
  15. int most, least;
  16. {
  17.     object z;
  18.  
  19.     z = alloc_object(t_bignum);
  20.     vs_push(z);
  21.     z->big.big_car = least;
  22.     z->big.big_cdr = NULL;
  23.     z = (object)(z->big.big_cdr
  24.     = (struct bignum *)alloc_object(t_bignum));
  25.     z->big.big_car = most;
  26.     z->big.big_cdr = NULL;
  27.     return(vs_pop);
  28. }    
  29.  
  30. object
  31. bignum3(most, middle, least)
  32. int most, middle, least;
  33. {
  34.     object z;
  35.  
  36.     z = alloc_object(t_bignum);
  37.     vs_push(z);
  38.     z->big.big_car = least;
  39.     z->big.big_cdr = NULL;
  40.     z = (object)(z->big.big_cdr
  41.     = (struct bignum *)alloc_object(t_bignum));
  42.     z->big.big_car = middle;
  43.     z->big.big_cdr = NULL;
  44.     z = (object)(z->big.big_cdr
  45.     = (struct bignum *)alloc_object(t_bignum));
  46.     z->big.big_car = most;
  47.     z->big.big_cdr = NULL;
  48.     return(vs_pop);
  49. }    
  50.  
  51. object
  52. fixnum_times(i, j)
  53. int i, j;
  54. {
  55.  
  56.     int s, h, l;
  57.     object z;
  58.  
  59.     if (i == 0 || j == 0)
  60.         return(small_fixnum(0));
  61.     if (i < 0) {
  62.         if (i == MOST_NEGATIVE_FIX) {
  63.             if (j == MOST_NEGATIVE_FIX)
  64.                 return(bignum3(1, 0, 0));
  65.             return(bignum2(-j, 0));
  66.         }
  67.         i = -i;
  68.         s = -1;
  69.     } else
  70.         s = 1;
  71.     if (j < 0) {
  72.         if (j == MOST_NEGATIVE_FIX) {
  73.             if (s < 0)
  74.                 return(bignum2(i, 0));
  75.             else
  76.                 return(bignum2(-i, 0));
  77.         }
  78.         j = -j;
  79.         s = -s;
  80.     }
  81.     extended_mul(i, j, 0, &h, &l);
  82.     if (h != 0) {
  83.         if (s < 0) {
  84.             if (l == 0)
  85.                 if (h == 1)
  86.                     return(make_fixnum(
  87.                         MOST_NEGATIVE_FIX));
  88.                 else
  89.                     return(bignum2(-h, 0));
  90.             else
  91.                 return(bignum2(~h, (-l) & MASK));
  92.         } else
  93.             return(bignum2(h, l & MASK));
  94.     } else
  95.         return(make_fixnum(s*l));
  96. }
  97.  
  98. object
  99. fix_big_times(i, b)
  100. int i;
  101. object b;
  102. {
  103.     int j, s;
  104.     struct bignum *x;
  105.     vs_mark;
  106.  
  107.     if (i == 1)
  108.         return(b);
  109.     if (i == -1)
  110.         return(number_negate(b));
  111.     x = copy_big(b);
  112.     vs_push((object)x);    /* for GC */
  113.     if ((s = big_sign(x)) < 0)
  114.         complement_big(x);
  115.     if (i < 0) {
  116.         if (i == MOST_NEGATIVE_FIX) {
  117.             s = -s;
  118.             x = (struct bignum *)alloc_object(t_bignum);
  119.             x->big_car = 0;
  120.             x->big_cdr = (struct bignum *)(vs_head);
  121.             goto L;
  122.         }
  123.         i = -i;
  124.         s = -s;
  125.     }
  126.     mul_int_big(i, x);
  127. L:
  128.     if (s < 0)
  129.         complement_big(x);
  130.     x = (struct bignum *)normalize_big_to_object(x);
  131.     vs_reset;
  132.     return((object)x);
  133. }
  134.  
  135. object
  136. big_big_times(x, y)
  137. object    x, y;
  138. {
  139.     int    i, j;
  140.     struct bignum *z;
  141.     vs_mark;
  142.  
  143.     if ((i = big_sign(x)) < 0) {
  144.         x = (object)big_minus(x);
  145.         vs_push(x);
  146.     }
  147.     if ((j = big_sign(y)) < 0) {
  148.         y = (object)big_minus(y);
  149.         vs_push(y);
  150.     }
  151.     z = big_times(x, y);
  152.     vs_push(((object)z));
  153.     if (i > 0 && j < 0 || i < 0 && j > 0)
  154.         complement_big(z);
  155.     z = (struct bignum *)normalize_big_to_object(z);
  156.     vs_reset;
  157.     return((object)z);
  158. }
  159.  
  160. object
  161. number_to_complex(x)
  162. object x;
  163. {
  164.     object z;
  165.  
  166.     switch (type_of(x)) {
  167.  
  168.     case t_fixnum:
  169.     case t_bignum:
  170.     case t_ratio:
  171.     case t_shortfloat:
  172.     case t_longfloat:
  173.         z = alloc_object(t_complex);
  174.         z->cmp.cmp_real = x;
  175.         z->cmp.cmp_imag = small_fixnum(0);
  176.         return(z);
  177.  
  178.     case t_complex:
  179.         return(x);
  180.  
  181.     default:
  182.         FEwrong_type_argument(Snumber, x);
  183.     }
  184. }
  185.  
  186. object
  187. number_plus(x, y)
  188. object x, y;
  189. {
  190.     int i, j, k;
  191.     double dx, dy;
  192.     object z, z1;
  193.     vs_mark;
  194.     
  195.     switch (type_of(x)) {
  196.  
  197.     case t_fixnum:
  198.         switch(type_of(y)) {
  199.         case t_fixnum:
  200.             if((i = fix(x)) == 0)
  201.                 return(y);
  202.             if((j = fix(y)) == 0)
  203.                 return(x);
  204.             if(i > 0)
  205.                 if (j > 0)
  206.                     if ((k = i + j) > 0)
  207.                         return(make_fixnum(k));
  208.                     else
  209.                         return(bignum2(1, k & MASK));
  210.                 else
  211.                     return(make_fixnum(i + j));
  212.             else
  213.                     if(j > 0)
  214.                     return(make_fixnum(i + j));
  215.                 else
  216.                     if ((k = i + j) < 0)
  217.                         return(make_fixnum(k));
  218.                     else
  219.                         return(bignum2(-2, k & MASK));
  220.         case t_bignum:
  221.             if ((i = fix(x)) == 0)
  222.                 return(y);
  223.             z = (object)copy_big(y);
  224.             vs_push(z);
  225.             if(i > 0)
  226.                 add_int_big(i, z);
  227.             else if (i == MOST_NEGATIVE_FIX)
  228.                 sub_int_big(1, z->big.big_cdr);
  229.             else
  230.                 sub_int_big(-i, z);
  231.                 z = normalize_big_to_object(z);
  232.             vs_reset;
  233.             return(z);
  234.         case t_ratio:
  235.             vs_push(number_times(x, y->rat.rat_den));
  236.             z = number_plus(vs_top[-1], y->rat.rat_num);
  237.             vs_push(z);
  238.             z = make_ratio(z, y->rat.rat_den);
  239.             vs_reset;
  240.             return(z);
  241.         case t_shortfloat:
  242.             dx = (double)(fix(x));
  243.             dy = (double)(sf(y));
  244.             goto SHORTFLOAT;
  245.         case t_longfloat:
  246.             dx = (double)(fix(x));
  247.             dy = lf(y);
  248.             goto LONGFLOAT;
  249.         case t_complex:
  250.             goto COMPLEX;
  251.         default:
  252.             FEwrong_type_argument(Snumber, y);
  253.         }
  254.  
  255.     case t_bignum:
  256.         switch (type_of(y)) {
  257.         case t_fixnum:
  258.             if((j = fix(y)) == 0)
  259.                 return(x);
  260.             z = (object)copy_big(x);
  261.             vs_push(z);
  262.             if(j > 0)
  263.                 add_int_big(j, z);
  264.             else if (j == MOST_NEGATIVE_FIX)
  265.                 sub_int_big(1, z->big.big_cdr);
  266.             else
  267.                 sub_int_big(-j, z);
  268.             z = normalize_big_to_object(z);
  269.             vs_reset;
  270.             return(z);
  271.         case t_bignum:
  272.             z = (object)big_plus(x, y);
  273.             vs_push(z);
  274.             z = normalize_big_to_object(z);
  275.             vs_reset;
  276.             return(z);
  277.         case t_ratio:
  278.             vs_push(number_times(x, y->rat.rat_den));
  279.             z = number_plus(vs_top[-1], y->rat.rat_num);
  280.             vs_push(z);
  281.             z = make_ratio(z, y->rat.rat_den);
  282.             vs_reset;
  283.             return(z);
  284.         case t_shortfloat:
  285.             dx = number_to_double(x);
  286.             dy = (double)(sf(y));
  287.             goto SHORTFLOAT;
  288.         case t_longfloat:
  289.             dx = number_to_double(x);
  290.             dy = lf(y);
  291.             goto LONGFLOAT;
  292.         case t_complex:
  293.             goto COMPLEX;
  294.         default:
  295.             FEwrong_type_argument(Snumber, y);
  296.         }
  297.  
  298.     case t_ratio:
  299.         switch (type_of(y)) {
  300.         case t_fixnum:
  301.         case t_bignum:
  302.             vs_push(number_times(x->rat.rat_den, y));
  303.             z = number_plus(x->rat.rat_num, vs_top[-1]);
  304.             vs_push(z);
  305.             z = make_ratio(z, x->rat.rat_den);
  306.             vs_reset;
  307.             return(z);
  308.         case t_ratio:
  309.             vs_push(number_times(x->rat.rat_num,y->rat.rat_den));
  310.             vs_push(number_times(x->rat.rat_den,y->rat.rat_num));
  311.             z = number_plus(vs_top[-2], vs_top[-1]);
  312.             vs_push(z);
  313.             vs_push(number_times(x->rat.rat_den,y->rat.rat_den));
  314.             z = make_ratio(z, vs_top[-1]);
  315.             vs_reset;
  316.             return(z);
  317.         case t_shortfloat:
  318.             dx = number_to_double(x);
  319.             dy = (double)(sf(y));
  320.             goto SHORTFLOAT;
  321.         case t_longfloat:
  322.             dx = number_to_double(x);
  323.             dy = lf(y);
  324.             goto LONGFLOAT;
  325.         case t_complex:
  326.             goto COMPLEX;
  327.         default:
  328.             FEwrong_type_argument(Snumber, y);
  329.         }
  330.  
  331.     case t_shortfloat:
  332.         switch (type_of(y)) {
  333.         case t_fixnum:
  334.             dx = (double)(sf(x));
  335.             dy = (double)(fix(y));
  336.             goto SHORTFLOAT;
  337.         case t_shortfloat:
  338.             dx = (double)(sf(x));
  339.             dy = (double)(sf(y));
  340.             goto SHORTFLOAT;
  341.         case t_longfloat:
  342.             dx = (double)(sf(x));
  343.             dy = lf(y);
  344.             goto LONGFLOAT;
  345.         case t_complex:
  346.             goto COMPLEX;
  347.         default:
  348.             dx = (double)(sf(x));
  349.             dy = number_to_double(y);
  350.             goto SHORTFLOAT;
  351.         }
  352.     SHORTFLOAT:
  353.         z = alloc_object(t_shortfloat);
  354.         sf(z) = (shortfloat)(dx + dy);
  355.         return(z);
  356.  
  357.     case t_longfloat:
  358.         dx = lf(x);
  359.         switch (type_of(y)) {
  360.         case t_fixnum:
  361.             dy = (double)(fix(y));
  362.             goto LONGFLOAT;
  363.         case t_shortfloat:
  364.             dy = (double)(sf(y));
  365.             goto LONGFLOAT;
  366.         case t_longfloat:
  367.             dy = lf(y);
  368.             goto LONGFLOAT;
  369.         case t_complex:
  370.             goto COMPLEX;
  371.         default:
  372.             dy = number_to_double(y);
  373.             goto LONGFLOAT;
  374.         }
  375.     LONGFLOAT:
  376.         z = alloc_object(t_longfloat);
  377.         lf(z) = dx + dy;
  378.         return(z);
  379.  
  380.     case t_complex:
  381.     COMPLEX:
  382.         x = number_to_complex(x);
  383.         vs_push(x);
  384.         y = number_to_complex(y);
  385.         vs_push(y);
  386.         vs_push(number_plus(x->cmp.cmp_real, y->cmp.cmp_real));
  387.         vs_push(number_plus(x->cmp.cmp_imag, y->cmp.cmp_imag));
  388.         z = make_complex(vs_top[-2], vs_top[-1]);
  389.         vs_reset;
  390.         return(z);
  391.  
  392.     default:
  393.         FEwrong_type_argument(Snumber, x);
  394.     }
  395. }
  396.  
  397. object
  398. one_plus(x)
  399. object x;
  400. {
  401.     int i;
  402.     double dx;
  403.     object z, z1;
  404.     vs_mark;
  405.     
  406.     switch (type_of(x)) {
  407.  
  408.     case t_fixnum:
  409.         i = fix(x);
  410.         if(i == 0)
  411.             return(small_fixnum(1));
  412.         if(i > 0)
  413.             if (++i > 0) {
  414.                 if (-SMALL_FIXNUM_LIMIT <= i &&
  415.                     i < SMALL_FIXNUM_LIMIT)
  416.                     return(small_fixnum(i));
  417.                 z = alloc_object(t_fixnum);
  418.                 fix(z) = i;
  419.                 return(z);
  420.             } else
  421.                 return(bignum2(1, i & MASK));
  422.         else {
  423.             i++;
  424.             if (-SMALL_FIXNUM_LIMIT <= i &&
  425.                 i < SMALL_FIXNUM_LIMIT)
  426.                 return(small_fixnum(i));
  427.             z = alloc_object(t_fixnum);
  428.             fix(z) = i;
  429.             return(z);
  430.         }
  431.  
  432.     case t_bignum:
  433.         return(number_plus(x, small_fixnum(1)));
  434.  
  435.     case t_ratio:
  436.         z = number_plus(x->rat.rat_num, x->rat.rat_den);
  437.         vs_push(z);
  438.         z = make_ratio(z, x->rat.rat_den);
  439.         vs_reset;
  440.         return(z);
  441.  
  442.     case t_shortfloat:
  443.         dx = (double)(sf(x));
  444.         z = alloc_object(t_shortfloat);
  445.         sf(z) = (shortfloat)(dx + 1.0);
  446.         return(z);
  447.  
  448.     case t_longfloat:
  449.         dx = lf(x);
  450.         z = alloc_object(t_longfloat);
  451.         lf(z) = dx + 1.0;
  452.         return(z);
  453.  
  454.     case t_complex:
  455.     COMPLEX:
  456.         vs_push(one_plus(x->cmp.cmp_real));
  457.         z = make_complex(vs_top[-1], x->cmp.cmp_imag);
  458.         vs_reset;
  459.         return(z);
  460.  
  461.     default:
  462.         FEwrong_type_argument(Snumber, x);
  463.     }
  464. }
  465.  
  466. object
  467. number_minus(x, y)
  468. object x, y;
  469. {
  470.     int i, j, k;
  471.     double dx, dy;
  472.     object z, z1;
  473.     vs_mark;
  474.     
  475.     switch (type_of(x)) {
  476.  
  477.     case t_fixnum:
  478.         switch(type_of(y)) {
  479.         case t_fixnum:
  480.             if((j = fix(y)) == 0)
  481.                 return(x);
  482.             if((i = fix(x)) >= 0)
  483.                 if (j < 0)
  484.                     if ((k = i - j) > 0)
  485.                         return(make_fixnum(k));
  486.                     else
  487.                         return(bignum2(1, k & MASK));
  488.                 else
  489.                     return(make_fixnum(i - j));
  490.             else
  491.                     if(j < 0)
  492.                     return(make_fixnum(i - j));
  493.                 else
  494.                     if ((k = i - j) < 0)
  495.                         return(make_fixnum(k));
  496.                     else
  497.                         return(bignum2(-2, k & MASK));
  498.         case t_bignum:
  499.             z = (object)big_minus(y);
  500.             vs_push(z);
  501.             if ((i = fix(x)) == 0)
  502.                 ;
  503.             else if(i > 0)
  504.                 add_int_big(i, z);
  505.             else if (i == MOST_NEGATIVE_FIX)
  506.                 sub_int_big(1, z->big.big_cdr);
  507.             else
  508.                 sub_int_big(-i, z);
  509.                 z = normalize_big_to_object(z);
  510.             vs_reset;
  511.             return(z);
  512.         case t_ratio:
  513.             vs_push(number_times(x, y->rat.rat_den));
  514.             z = number_minus(vs_top[-1], y->rat.rat_num);
  515.             vs_push(z);
  516.             z = make_ratio(z, y->rat.rat_den);
  517.             vs_reset;
  518.             return(z);
  519.         case t_shortfloat:
  520.             dx = (double)(fix(x));
  521.             dy = (double)(sf(y));
  522.             goto SHORTFLOAT;
  523.         case t_longfloat:
  524.             dx = (double)(fix(x));
  525.             dy = lf(y);
  526.             goto LONGFLOAT;
  527.         case t_complex:
  528.             goto COMPLEX;
  529.         default:
  530.             FEwrong_type_argument(Snumber, y);
  531.         }
  532.  
  533.     case t_bignum:
  534.         switch (type_of(y)) {
  535.         case t_fixnum:
  536.             if((j = fix(y)) == 0)
  537.                 return(x);
  538.             z = (object)copy_big(x);
  539.             vs_push(z);
  540.             if (j > 0)
  541.                 sub_int_big(j, z);
  542.             else if (j == MOST_NEGATIVE_FIX)
  543.                 add_int_big(1, z->big.big_cdr);
  544.             else
  545.                 add_int_big(-j, z);
  546.             z = normalize_big_to_object(z);
  547.             vs_reset;
  548.             return(z);
  549.         case t_bignum:
  550.             y = (object)big_minus(y);
  551.             vs_push(y);
  552.             z = (object)big_plus(x, y);
  553.             vs_push(z);
  554.             z = normalize_big_to_object(z);
  555.             vs_reset;
  556.             return(z);
  557.         case t_ratio:
  558.             vs_push(number_times(x, y->rat.rat_den));
  559.             z = number_minus(vs_top[-1], y->rat.rat_num);
  560.             vs_push(z);
  561.             z = make_ratio(z, y->rat.rat_den);
  562.             vs_reset;
  563.             return(z);
  564.         case t_shortfloat:
  565.             dx = number_to_double(x);
  566.             dy = (double)(sf(y));
  567.             goto SHORTFLOAT;
  568.         case t_longfloat:
  569.             dx = number_to_double(x);
  570.             dy = lf(y);
  571.             goto LONGFLOAT;
  572.         case t_complex:
  573.             goto COMPLEX;
  574.         default:
  575.             FEwrong_type_argument(Snumber, y);
  576.         }
  577.  
  578.     case t_ratio:
  579.         switch (type_of(y)) {
  580.         case t_fixnum:
  581.         case t_bignum:
  582.             vs_push(number_times(x->rat.rat_den, y));
  583.             z = number_minus(x->rat.rat_num, vs_top[-1]);
  584.             vs_push(z);
  585.             z = make_ratio(z, x->rat.rat_den);
  586.             vs_reset;
  587.             return(z);
  588.         case t_ratio:
  589.             vs_push(number_times(x->rat.rat_num,y->rat.rat_den));
  590.             vs_push(number_times(x->rat.rat_den,y->rat.rat_num));
  591.             z = number_minus(vs_top[-2], vs_top[-1]);
  592.             vs_push(z);
  593.             vs_push(number_times(x->rat.rat_den,y->rat.rat_den));
  594.             z = make_ratio(z, vs_top[-1]);
  595.             vs_reset;
  596.             return(z);
  597.         case t_shortfloat:
  598.             dx = number_to_double(x);
  599.             dy = (double)(sf(y));
  600.             goto SHORTFLOAT;
  601.         case t_longfloat:
  602.             dx = number_to_double(x);
  603.             dy = lf(y);
  604.             goto LONGFLOAT;
  605.         case t_complex:
  606.             goto COMPLEX;
  607.         default:
  608.             FEwrong_type_argument(Snumber, y);
  609.         }
  610.  
  611.     case t_shortfloat:
  612.         switch (type_of(y)) {
  613.         case t_fixnum:
  614.             dx = (double)(sf(x));
  615.             dy = (double)(fix(y));
  616.             goto SHORTFLOAT;
  617.         case t_shortfloat:
  618.             dx = (double)(sf(x));
  619.             dy = (double)(sf(y));
  620.             goto SHORTFLOAT;
  621.         case t_longfloat:
  622.             dx = (double)(sf(x));
  623.             dy = lf(y);
  624.             goto LONGFLOAT;
  625.         case t_complex:
  626.             goto COMPLEX;
  627.         default:
  628.             dx = (double)(sf(x));
  629.             dy = number_to_double(y);
  630.             goto SHORTFLOAT;
  631.         }
  632.     SHORTFLOAT:
  633.         z = alloc_object(t_shortfloat);
  634.         sf(z) = (shortfloat)(dx - dy);
  635.         return(z);
  636.  
  637.     case t_longfloat:
  638.         dx = lf(x);
  639.         switch (type_of(y)) {
  640.         case t_fixnum:
  641.             dy = (double)(fix(y));
  642.             goto LONGFLOAT;
  643.         case t_shortfloat:
  644.             dy = (double)(sf(y));
  645.             goto LONGFLOAT;
  646.         case t_longfloat:
  647.             dy = lf(y);
  648.             goto LONGFLOAT;
  649.         case t_complex:
  650.             goto COMPLEX;
  651.         default:
  652.             dy = number_to_double(y);
  653.         }
  654.     LONGFLOAT:
  655.         z = alloc_object(t_longfloat);
  656.         lf(z) = dx - dy;
  657.         return(z);
  658.  
  659.     case t_complex:
  660.     COMPLEX:
  661.         x = number_to_complex(x);
  662.         vs_push(x);
  663.         y = number_to_complex(y);
  664.         vs_push(y);
  665.         vs_push(number_minus(x->cmp.cmp_real, y->cmp.cmp_real));
  666.         vs_push(number_minus(x->cmp.cmp_imag, y->cmp.cmp_imag));
  667.         z = make_complex(vs_top[-2], vs_top[-1]);
  668.         vs_reset;
  669.         return(z);
  670.  
  671.     default:
  672.         FEwrong_type_argument(Snumber, x);
  673.     }
  674. }
  675.  
  676. object
  677. one_minus(x)
  678. object x;
  679. {
  680.     int i;
  681.     double dx;
  682.     object z, z1;
  683.     vs_mark;
  684.     
  685.     switch (type_of(x)) {
  686.  
  687.     case t_fixnum:
  688.         i = fix(x);
  689.         if(i == 0)
  690.             return(small_fixnum(-1));
  691.         if(i > 0) {
  692.             i--;
  693.             if (-SMALL_FIXNUM_LIMIT <= i &&
  694.                 i < SMALL_FIXNUM_LIMIT)
  695.                 return(small_fixnum(i));
  696.             z = alloc_object(t_fixnum);
  697.             fix(z) = i;
  698.             return(z);
  699.         } else
  700.             if (--i < 0) {
  701.                 if (-SMALL_FIXNUM_LIMIT <= i &&
  702.                     i < SMALL_FIXNUM_LIMIT)
  703.                     return(small_fixnum(i));
  704.                 z = alloc_object(t_fixnum);
  705.                 fix(z) = i;
  706.                 return(z);
  707.             } else
  708.                 return(bignum2(-2, i & MASK));
  709.  
  710.     case t_bignum:
  711.         return(number_minus(x, small_fixnum(1)));
  712.  
  713.     case t_ratio:
  714.         z = number_minus(x->rat.rat_num, x->rat.rat_den);
  715.         vs_push(z);
  716.         z = make_ratio(z, x->rat.rat_den);
  717.         vs_reset;
  718.         return(z);
  719.  
  720.     case t_shortfloat:
  721.         dx = (double)(sf(x));
  722.         z = alloc_object(t_shortfloat);
  723.         sf(z) = (shortfloat)(dx - 1.0);
  724.         return(z);
  725.  
  726.     case t_longfloat:
  727.         dx = lf(x);
  728.         z = alloc_object(t_longfloat);
  729.         lf(z) = dx - 1.0;
  730.         return(z);
  731.  
  732.     case t_complex:
  733.     COMPLEX:
  734.         vs_push(one_minus(x->cmp.cmp_real));
  735.         z = make_complex(vs_top[-1], x->cmp.cmp_imag);
  736.         vs_reset;
  737.         return(z);
  738.  
  739.     default:
  740.         FEwrong_type_argument(Snumber, x);
  741.     }
  742. }
  743.  
  744. object
  745. number_negate(x)
  746. object x;
  747. {
  748.     object    z, z1;
  749.     vs_mark;
  750.  
  751.     switch (type_of(x)) {
  752.  
  753.     case t_fixnum:
  754.         if(fix(x) == MOST_NEGATIVE_FIX)
  755.             return(bignum2(1, 0));
  756.         else
  757.             return(make_fixnum(-fix(x)));
  758.  
  759.     case t_bignum:
  760.         z = (object)big_minus(x);
  761.         vs_push(z);
  762.         z = normalize_big_to_object(z);
  763.         vs_reset;
  764.         return(z);
  765.  
  766.     case t_ratio:
  767.         z1 = number_negate(x->rat.rat_num);
  768.         vs_push(z1);
  769.         z = alloc_object(t_ratio);
  770.         z->rat.rat_num = z1;
  771.         z->rat.rat_den = x->rat.rat_den;
  772.         vs_reset;
  773.         return(z);
  774.  
  775.     case t_shortfloat:
  776.         z = alloc_object(t_shortfloat);
  777.         sf(z) = -sf(x);
  778.         return(z);
  779.  
  780.     case t_longfloat:
  781.         z = alloc_object(t_longfloat);
  782.         lf(z) = -lf(x);
  783.         return(z);
  784.  
  785.     case t_complex:
  786.         vs_push(number_negate(x->cmp.cmp_real));
  787.         vs_push(number_negate(x->cmp.cmp_imag));
  788.         z = make_complex(vs_top[-2], vs_top[-1]);
  789.         vs_reset;
  790.         return(z);
  791.  
  792.     default:
  793.         FEwrong_type_argument(Snumber, x);
  794.     }
  795. }
  796.  
  797. object
  798. number_times(x, y)
  799. object x, y;
  800. {
  801.     object z;
  802.     double dx, dy;
  803.     vs_mark;
  804.  
  805.     switch (type_of(x)) {
  806.  
  807.     case t_fixnum:
  808.         switch (type_of(y)) {
  809.         case t_fixnum:
  810.             return(fixnum_times(fix(x), fix(y)));
  811.         case t_bignum:
  812.             return(fix_big_times(fix(x), y));
  813.         case t_ratio:
  814.             vs_push(number_times(x, y->rat.rat_num));
  815.             z = make_ratio(vs_top[-1], y->rat.rat_den);
  816.             vs_reset;
  817.             return(z);
  818.         case t_shortfloat:
  819.             dx = (double)(fix(x));
  820.             dy = (double)(sf(y));
  821.             goto SHORTFLOAT;
  822.         case t_longfloat:
  823.             dx = (double)(fix(x));
  824.             dy = lf(y);
  825.             goto LONGFLOAT;
  826.         case t_complex:
  827.             goto COMPLEX;
  828.         default:
  829.             FEwrong_type_argument(Snumber, y);
  830.         }
  831.  
  832.     case t_bignum:
  833.         switch (type_of(y)) {
  834.         case t_fixnum:
  835.             return(fix_big_times(fix(y), x));
  836.         case t_bignum:
  837.             return(big_big_times(x, y));
  838.         case t_ratio:
  839.             vs_push(number_times(x, y->rat.rat_num));
  840.             z = make_ratio(vs_top[-1], y->rat.rat_den);
  841.             vs_reset;
  842.             return(z);
  843.         case t_shortfloat:
  844.             dx = number_to_double(x);
  845.             dy = (double)(sf(y));
  846.             goto SHORTFLOAT;
  847.         case t_longfloat:
  848.             dx = number_to_double(x);
  849.             dy = lf(y);
  850.             goto LONGFLOAT;
  851.         case t_complex:
  852.             goto COMPLEX;
  853.         default:
  854.             FEwrong_type_argument(Snumber, y);
  855.         }
  856.  
  857.     case t_ratio:
  858.         switch (type_of(y)) {
  859.         case t_fixnum:
  860.         case t_bignum:
  861.             vs_push(number_times(x->rat.rat_num, y));
  862.             z = make_ratio(vs_top[-1], x->rat.rat_den);
  863.             vs_reset;
  864.             return(z);
  865.         case t_ratio:
  866.             vs_push(number_times(x->rat.rat_num,y->rat.rat_num));
  867.             vs_push(number_times(x->rat.rat_den,y->rat.rat_den));
  868.             z = make_ratio(vs_top[-2], vs_top[-1]);
  869.             vs_reset;
  870.             return(z);
  871.         case t_shortfloat:
  872.             dx = number_to_double(x);
  873.             dy = (double)(sf(y));
  874.             goto SHORTFLOAT;
  875.         case t_longfloat:
  876.             dx = number_to_double(x);
  877.             dy = lf(y);
  878.             goto LONGFLOAT;
  879.         case t_complex:
  880.             goto COMPLEX;
  881.         default:
  882.             FEwrong_type_argument(Snumber, y);
  883.         }
  884.  
  885.     case t_shortfloat:
  886.         switch (type_of(y)) {
  887.         case t_fixnum:
  888.             dx = (double)(sf(x));
  889.             dy = (double)(fix(y));
  890.             goto SHORTFLOAT;
  891.         case t_shortfloat:
  892.             dx = (double)(sf(x));
  893.             dy = (double)(sf(y));
  894.             goto SHORTFLOAT;
  895.         case t_longfloat:
  896.             dx = (double)(sf(x));
  897.             dy = lf(y);
  898.             goto LONGFLOAT;
  899.         case t_complex:
  900.             goto COMPLEX;
  901.         default:
  902.             dx = (double)(sf(x));
  903.             dy = number_to_double(y);
  904.             break;
  905.         }
  906.     SHORTFLOAT:
  907.         z = alloc_object(t_shortfloat);
  908.         sf(z) = (shortfloat)(dx * dy);
  909.         return(z);
  910.  
  911.     case t_longfloat:
  912.         dx = lf(x);
  913.         switch (type_of(y)) {
  914.         case t_fixnum:
  915.             dy = (double)(fix(y));
  916.             goto LONGFLOAT;
  917.         case t_shortfloat:
  918.             dy = (double)(sf(y));
  919.             goto LONGFLOAT;
  920.         case t_longfloat:
  921.             dy = lf(y);
  922.             goto LONGFLOAT;
  923.         case t_complex:
  924.             goto COMPLEX;
  925.         default:
  926.             dy = number_to_double(y);
  927.         }
  928.     LONGFLOAT:
  929.         z = alloc_object(t_longfloat);
  930.         lf(z) = dx * dy;
  931.         return(z);
  932.  
  933.     case t_complex:
  934.     COMPLEX:
  935.     {
  936.         object z1, z2, z11, z12, z21, z22;
  937.  
  938.         x = number_to_complex(x);
  939.         vs_push(x);
  940.         y = number_to_complex(y);
  941.         vs_push(y);
  942.         z11 = number_times(x->cmp.cmp_real, y->cmp.cmp_real);
  943.         vs_push(z11);
  944.         z12 = number_times(x->cmp.cmp_imag, y->cmp.cmp_imag);
  945.         vs_push(z12);
  946.         z21 = number_times(x->cmp.cmp_imag, y->cmp.cmp_real);
  947.         vs_push(z21);
  948.         z22 = number_times(x->cmp.cmp_real, y->cmp.cmp_imag);
  949.         vs_push(z22);
  950.         z1 =  number_minus(z11, z12);
  951.         vs_push(z1);
  952.         z2 =  number_plus(z21, z22);
  953.         vs_push(z2);
  954.         z = make_complex(z1, z2);
  955.         vs_reset;
  956.         return(z);
  957.     }
  958.  
  959.     default:
  960.         FEwrong_type_argument(Snumber, x);
  961.     }
  962. }
  963.  
  964. object
  965. number_divide(x, y)
  966. object x, y;
  967. {
  968.     object z;
  969.     double dx, dy;
  970.     vs_mark;
  971.  
  972.     switch (type_of(x)) {
  973.  
  974.     case t_fixnum:
  975.     case t_bignum:
  976.         switch (type_of(y)) {
  977.         case t_fixnum:
  978.         case t_bignum:
  979.             if(number_zerop(y) == TRUE)
  980.                 zero_divisor();
  981.             if (number_minusp(y) == TRUE) {
  982.                 x = number_negate(x);
  983.                 vs_push(x);
  984.                 y = number_negate(y);
  985.                 vs_push(y);
  986.             }
  987.             z = make_ratio(x, y);
  988.             vs_reset;
  989.             return(z);
  990.         case t_ratio:
  991.             if(number_zerop(y->rat.rat_num))
  992.                 zero_divisor();
  993.             vs_push(number_times(x, y->rat.rat_den));
  994.             z = make_ratio(vs_top[-1], y->rat.rat_num);
  995.             vs_reset;
  996.             return(z);
  997.         case t_shortfloat:
  998.             dx = number_to_double(x);
  999.             dy = (double)(sf(y));
  1000.             goto SHORTFLOAT;
  1001.         case t_longfloat:
  1002.             dx = number_to_double(x);
  1003.             dy = lf(y);
  1004.             goto LONGFLOAT;
  1005.         case t_complex:
  1006.             goto COMPLEX;
  1007.         default:
  1008.             FEwrong_type_argument(Snumber, y);
  1009.         }
  1010.  
  1011.     case t_ratio:
  1012.         switch (type_of(y)) {
  1013.         case t_fixnum:
  1014.         case t_bignum:
  1015.             if (number_zerop(y))
  1016.                 zero_divisor();
  1017.             vs_push(number_times(x->rat.rat_den, y));
  1018.             z = make_ratio(x->rat.rat_num, vs_top[-1]);
  1019.             vs_reset;
  1020.             return(z);
  1021.         case t_ratio:
  1022.             vs_push(number_times(x->rat.rat_num,y->rat.rat_den));
  1023.             vs_push(number_times(x->rat.rat_den,y->rat.rat_num));
  1024.             z = make_ratio(vs_top[-2], vs_top[-1]);
  1025.             vs_reset;
  1026.             return(z);
  1027.         case t_shortfloat:
  1028.             dx = number_to_double(x);
  1029.             dy = (double)(sf(y));
  1030.             goto SHORTFLOAT;
  1031.         case t_longfloat:
  1032.             dx = number_to_double(x);
  1033.             dy = lf(y);
  1034.             goto LONGFLOAT;
  1035.         case t_complex:
  1036.             goto COMPLEX;
  1037.         default:
  1038.             FEwrong_type_argument(Snumber, y);
  1039.         }
  1040.  
  1041.     case t_shortfloat:
  1042.         switch (type_of(y)) {
  1043.         case t_fixnum:
  1044.             dx = (double)(sf(x));
  1045.             dy = (double)(fix(y));
  1046.             goto SHORTFLOAT;
  1047.         case t_shortfloat:
  1048.             dx = (double)(sf(x));
  1049.             dy = (double)(sf(y));
  1050.             goto SHORTFLOAT;
  1051.         case t_longfloat:
  1052.             dx = (double)(sf(x));
  1053.             dy = lf(y);
  1054.             goto LONGFLOAT;
  1055.         case t_complex:
  1056.             goto COMPLEX;
  1057.         default:
  1058.             dx = (double)(sf(x));
  1059.             dy = number_to_double(y);
  1060.             goto LONGFLOAT;
  1061.         }
  1062.     SHORTFLOAT:
  1063.         z = alloc_object(t_shortfloat);
  1064.         if (dy == 0.0)
  1065.             zero_divisor();
  1066.         sf(z) = (shortfloat)(dx / dy);
  1067.         return(z);
  1068.  
  1069.  
  1070.     case t_longfloat:
  1071.         dx = lf(x);
  1072.         switch (type_of(y)) {
  1073.         case t_fixnum:
  1074.             dy = (double)(fix(y));
  1075.             goto LONGFLOAT;
  1076.         case t_shortfloat:
  1077.             dy = (double)(sf(y));
  1078.             goto LONGFLOAT;
  1079.         case t_longfloat:
  1080.             dy = lf(y);
  1081.             goto LONGFLOAT;
  1082.         case t_complex:
  1083.             goto COMPLEX;
  1084.         default:
  1085.             dy = number_to_double(y);
  1086.         }
  1087.     LONGFLOAT:
  1088.         z = alloc_object(t_longfloat);
  1089.         if (dy == 0.0)
  1090.             zero_divisor();
  1091.         lf(z) = dx / dy;
  1092.         return(z);
  1093.  
  1094.     case t_complex:
  1095.     COMPLEX:
  1096.     {
  1097.         object z1, z2, z3;
  1098.  
  1099.         x = number_to_complex(x);
  1100.         vs_push(x);
  1101.         y = number_to_complex(y);
  1102.         vs_push(y);
  1103.         z1 = number_times(y->cmp.cmp_real, y->cmp.cmp_real);
  1104.         vs_push(z1);
  1105.         z2 = number_times(y->cmp.cmp_imag, y->cmp.cmp_imag);
  1106.         vs_push(z2);
  1107.         if (number_zerop(z3 = number_plus(z1, z2)))
  1108.             zero_divisor();
  1109.         vs_push(z3);
  1110.         z1 = number_times(x->cmp.cmp_real, y->cmp.cmp_real);
  1111.         vs_push(z1);
  1112.         z2 = number_times(x->cmp.cmp_imag, y->cmp.cmp_imag);
  1113.         vs_push(z2);
  1114.         z1 = number_plus(z1, z2);
  1115.         vs_push(z1);
  1116.         z = number_times(x->cmp.cmp_imag, y->cmp.cmp_real);
  1117.         vs_push(z);
  1118.         z2 = number_times(x->cmp.cmp_real, y->cmp.cmp_imag);
  1119.         vs_push(z2);
  1120.         z2 = number_minus(z, z2);
  1121.         vs_push(z2);
  1122.         z1 = number_divide(z1, z3);
  1123.         vs_push(z1);
  1124.         z2 = number_divide(z2, z3);
  1125.         vs_push(z2);
  1126.         z = make_complex(z1, z2);
  1127.         vs_reset;
  1128.         return(z);
  1129.     }
  1130.  
  1131.     default:
  1132.         FEwrong_type_argument(Snumber, x);
  1133.     }
  1134. }
  1135.  
  1136. integer_quotient_remainder_1(x, y, qp, rp)
  1137. object x, y;
  1138. object *qp, *rp;
  1139. {
  1140.     enum type tx, ty;
  1141.     int i, j, q, r;
  1142.     vs_mark;
  1143.         
  1144.     tx = type_of(x);
  1145.     ty = type_of(y);
  1146.     if (tx == t_fixnum) {
  1147.          if (ty == t_fixnum) {
  1148.             if (fix(y) == 0)
  1149.                 zero_divisor();
  1150.             if (fix(y) == MOST_NEGATIVE_FIX)
  1151.                 if (fix(x) == MOST_NEGATIVE_FIX) {
  1152.                     *qp = small_fixnum(1);
  1153.                     *rp = small_fixnum(0);
  1154.                     return;
  1155.                 } else {
  1156.                     *qp = small_fixnum(0);
  1157.                     *rp = x;
  1158.                     return;
  1159.                 }
  1160.             if (fix(x) == MOST_NEGATIVE_FIX) {
  1161.                 if (fix(y) == 1) {
  1162.                     *qp = x;
  1163.                     *rp = small_fixnum(0);
  1164.                     return;
  1165.                 }
  1166.                 if (fix(y) == -1) {
  1167.                     *qp = bignum2(1, 0);
  1168.                     *rp = small_fixnum(0);
  1169.                     return;
  1170.                 }
  1171.                 if (fix(y) > 0) {
  1172.                     extended_div(fix(y), 1, 0,
  1173.                              &q, &r);
  1174.                     *qp = make_fixnum(-q);
  1175.                     vs_push(*qp);
  1176.                     *rp = make_fixnum(-r);
  1177.                     vs_reset;
  1178.                     return;
  1179.                 } else {
  1180.                     extended_div(-fix(y), 1, 0,
  1181.                              &q, &r);
  1182.                     *qp = make_fixnum(q);
  1183.                     vs_push(*qp);
  1184.                     *rp = make_fixnum(-r);
  1185.                     vs_reset;
  1186.                     return;
  1187.                 }
  1188.             }
  1189.             *qp = make_fixnum(fix(x) / fix(y));
  1190.             vs_push(*qp);
  1191.             *rp = make_fixnum(fix(x) % fix(y));
  1192.             vs_reset;
  1193.             return;
  1194.         }
  1195.         if (ty == t_bignum) {
  1196.             if (fix(x) == MOST_NEGATIVE_FIX &&
  1197.                 y->big.big_car == 0 &&
  1198.                 y->big.big_cdr->big_car == 1 &&
  1199.                 y->big.big_cdr->big_cdr == NULL) {
  1200.                 *qp = small_fixnum(-1);
  1201.                 *rp = small_fixnum(0);
  1202.                 return;
  1203.             }
  1204.             *qp = small_fixnum(0);
  1205.             *rp = x;
  1206.             return;
  1207.         } else
  1208.             FEwrong_type_argument(Sinteger, y);
  1209.     }
  1210.     if (tx == t_bignum) {
  1211.         if (ty == t_fixnum) {
  1212.             if (fix(y) == 0)
  1213.                 zero_divisor();
  1214.             x = (object)copy_big(x);
  1215.             vs_push(x);
  1216.             if((i = big_sign(x)) < 0) {
  1217.                 complement_big(x);
  1218.             }
  1219.             if (fix(y) == MOST_NEGATIVE_FIX) {
  1220.                 j = -i;
  1221.                 if (x->big.big_cdr == NULL) {
  1222.                     stretch_big(x, 0);
  1223.                 }
  1224.                 if (i < 0)
  1225.                     *rp =
  1226.                     make_fixnum(-x->big.big_car);
  1227.                 else
  1228.                     *rp =
  1229.                     make_fixnum(x->big.big_car);
  1230.                 vs_push(*rp);
  1231.                 x = (object)(x->big.big_cdr);
  1232.                 if (j < 0)
  1233.                     complement_big(x);
  1234.                 *qp=normalize_big_to_object(x);
  1235.                 vs_reset;
  1236.                 return;
  1237.             }
  1238.             if (fix(y) < 0) {
  1239.                 q = -fix(y);
  1240.                 j = -i;
  1241.             } else {
  1242.                 q = fix(y);
  1243.                 j = i;
  1244.             }
  1245.                      r = div_int_big(q, x);
  1246.             if (j < 0) {
  1247.                 complement_big(x);
  1248.             }
  1249.             *qp = normalize_big_to_object(x);
  1250.             vs_push(*qp);
  1251.             *rp = make_fixnum(i < 0 ? -r : r);
  1252.             vs_reset;
  1253.             return;
  1254.         }
  1255.         else if (ty == t_bignum) {
  1256.             if ((i = big_sign(x)) < 0) {
  1257.                 x = (object)big_minus(x);
  1258.                 vs_push(x);
  1259.             }
  1260.             if (big_sign(y) < 0) {
  1261.                 y = (object)big_minus(y);
  1262.                 vs_push(y);
  1263.                 j = -i;
  1264.             } else
  1265.                 j = i;
  1266.             big_quotient_remainder(x, y, qp, rp);
  1267.             vs_push(*qp);
  1268.             vs_push(*rp);
  1269.             if (j < 0) {
  1270.                 complement_big(*qp);
  1271.             }
  1272.             if (i < 0) {
  1273.                 complement_big(*rp);
  1274.             }
  1275.             *qp = normalize_big_to_object(*qp);
  1276.             vs_push(*qp);
  1277.             *rp = normalize_big_to_object(*rp);
  1278.             vs_reset;
  1279.             return;
  1280.         }
  1281.         else
  1282.             FEwrong_type_argument(Sinteger, y);
  1283.     }
  1284.     FEwrong_type_argument(Sinteger, y);
  1285. }
  1286.  
  1287. object
  1288. integer_divide1(x, y)
  1289. object x, y;
  1290. {
  1291.     object q, r;
  1292.  
  1293.     integer_quotient_remainder_1(x, y, &q, &r);
  1294.     return(q);
  1295. }
  1296.  
  1297. object
  1298. get_gcd(x, y)
  1299. object    x, y;
  1300. {
  1301.     int    i, j, k;
  1302.     object    q, r;
  1303.     vs_mark;
  1304.  
  1305.     if (number_minusp(x))
  1306.         x = number_negate(x);
  1307.     vs_push(x);
  1308.     if (number_minusp(y))
  1309.         y = number_negate(y);
  1310.     vs_push(y);
  1311.  
  1312. L:
  1313.     if (type_of(x) == t_fixnum && type_of(y) == t_fixnum) {
  1314.         i = fix(x);
  1315.         j = fix(y);
  1316. LL:
  1317.         if (i < j) {
  1318.             k = i;
  1319.             i = j;
  1320.             j = k;
  1321.         }
  1322.         if (j == 0) {
  1323.             vs_reset;
  1324.             return(make_fixnum(i));
  1325.         }
  1326.         k = i % j;
  1327.         i = j;
  1328.         j = k;
  1329.         goto LL;
  1330.     }
  1331.  
  1332.     if (number_compare(x, y) < 0) {
  1333.         r = x;
  1334.         x = y;
  1335.         y = r;
  1336.     }
  1337.     if (type_of(y) == t_fixnum && fix(y) == 0) {
  1338.         vs_reset;
  1339.         return(x);
  1340.     }
  1341.     integer_quotient_remainder_1(x, y, &q, &r);
  1342.     vs_top[-2] = x = y;
  1343.     vs_top[-1] = y = r;
  1344.     goto L;
  1345. }
  1346.  
  1347. /* (+          )   */
  1348. Lplus()
  1349. {
  1350.         int i, j;
  1351.     
  1352.     j = vs_top - vs_base;
  1353.     if (j == 0) {
  1354.         vs_push(small_fixnum(0));
  1355.         return;
  1356.     }
  1357.     for (i = 0;  i < j;  i++)
  1358.         check_type_number(&vs_base[i]);
  1359.     for (i = 1;  i < j;  i++)
  1360.         vs_base[0] = number_plus(vs_base[0], vs_base[i]);
  1361.     vs_top = vs_base+1;
  1362. }
  1363.  
  1364. Lminus()
  1365. {
  1366.     int i, j;
  1367.  
  1368.     j = vs_top - vs_base;
  1369.     if (j == 0)
  1370.         too_few_arguments();
  1371.     for (i = 0; i < j ; i++)
  1372.         check_type_number(&vs_base[i]);
  1373.     if (j == 1) {
  1374.         vs_base[0] = number_negate(vs_base[0]);
  1375.         return;
  1376.     }
  1377.     for (i = 1;  i < j;  i++)
  1378.         vs_base[0] = number_minus(vs_base[0], vs_base[i]);
  1379.     vs_top = vs_base+1;
  1380. }
  1381.  
  1382. Ltimes()
  1383. {
  1384.     int i, j;
  1385.  
  1386.     j = vs_top - vs_base;
  1387.     if (j == 0) {
  1388.         vs_push(small_fixnum(1));
  1389.         return;
  1390.     }
  1391.     for (i = 0;  i < j;  i++)
  1392.         check_type_number(&vs_base[i]);
  1393.     for (i = 1;  i < j;  i++)
  1394.         vs_base[0] = number_times(vs_base[0], vs_base[i]);
  1395.     vs_top = vs_base+1;
  1396. }
  1397.  
  1398. Ldivide()
  1399. {
  1400.     int i, j;
  1401.  
  1402.     j = vs_top - vs_base;
  1403.     if (j == 0)
  1404.         too_few_arguments();
  1405.     for(i = 0;  i < j;  i++)
  1406.         check_type_number(&vs_base[i]);
  1407.     if (j == 1) {
  1408.         vs_base[0] = number_divide(small_fixnum(1), vs_base[0]);
  1409.         return;
  1410.     }
  1411.     for (i = 1; i < j; i++)
  1412.         vs_base[0] = number_divide(vs_base[0], vs_base[i]);
  1413.     vs_top = vs_base+1;
  1414. }
  1415.  
  1416. Lone_plus()
  1417. {
  1418.     object x;
  1419.     
  1420.     check_arg(1);
  1421.     check_type_number(&vs_base[0]);
  1422.     vs_base[0] = one_plus(vs_base[0]);
  1423. }
  1424.  
  1425. Lone_minus()
  1426. {
  1427.     object x;
  1428.     
  1429.     check_arg(1);
  1430.     check_type_number(&vs_base[0]);
  1431.     vs_base[0] = one_minus(vs_base[0]);
  1432. }
  1433.  
  1434. Lconjugate()
  1435. {
  1436.     object    c, i;
  1437.  
  1438.     check_arg(1);
  1439.     check_type_number(&vs_base[0]);
  1440.     c = vs_base[0];
  1441.     if (type_of(c) == t_complex) {
  1442.         i = number_negate(c->cmp.cmp_imag);
  1443.         vs_push(i);
  1444.         vs_base[0] = make_complex(c->cmp.cmp_real, i);
  1445.         vs_pop;
  1446.     }
  1447. }
  1448.  
  1449. Lgcd()
  1450. {
  1451.     int i, narg;
  1452.  
  1453.     narg = vs_top - vs_base;
  1454.     if (narg == 0) {
  1455.         vs_push(small_fixnum(0));
  1456.         return;
  1457.     }
  1458.     for (i = 0;  i < narg;  i++)
  1459.         check_type_integer(&vs_base[i]);
  1460.     if (narg == 1) {
  1461.         if (number_minusp(vs_base[0]))
  1462.             vs_base[0] = number_negate(vs_base[0]);
  1463.         return;
  1464.     }
  1465.     for (i = 1;  i < narg;  i++)
  1466.         vs_base[0] = get_gcd(vs_base[0], vs_base[i]);
  1467.     vs_top = vs_base+1;
  1468. }
  1469.  
  1470. Llcm()
  1471. {
  1472.     object t, g;
  1473.     int i, narg;
  1474.  
  1475.     narg = vs_top - vs_base;
  1476.     if (narg == 0)
  1477.         too_few_arguments();
  1478.     for (i = 0;  i < narg;  i++)
  1479.         check_type_integer(&vs_base[i]);
  1480.     if (narg == 1) {
  1481.         if (number_minusp(vs_base[0]))
  1482.             vs_base[0] = number_negate(vs_base[0]);
  1483.         return;
  1484.     }
  1485.     for (i = 1;  i < narg;  i++) {
  1486.         t = number_times(vs_base[0], vs_base[i]);
  1487.         vs_push(t);
  1488.         g = get_gcd(vs_base[0], vs_base[i]);
  1489.         vs_push(g);
  1490.         vs_base[0] = number_divide(t, g);
  1491.         vs_pop;
  1492.         vs_pop;
  1493.     }
  1494.     if (number_minusp(vs_base[0]))
  1495.         vs_base[0] = number_negate(vs_base[0]);
  1496.     vs_top = vs_base+1;
  1497. }
  1498.  
  1499. zero_divisor()
  1500. {
  1501.     FEerror("Zero divisor.", 0);
  1502. }
  1503.  
  1504. init_num_arith()
  1505. {
  1506.     make_function("+", Lplus);
  1507.     make_function("-", Lminus);
  1508.     make_function("*", Ltimes);
  1509.     make_function("/", Ldivide);
  1510.     make_function("1+", Lone_plus);
  1511.     make_function("1-", Lone_minus);
  1512.     make_function("CONJUGATE", Lconjugate);
  1513.     make_function("GCD", Lgcd);
  1514.     make_function("LCM", Llcm);
  1515. }
  1516.